package com.ocom.exposeapi.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ocom.common.HttpUtils;
import com.ocom.common.constant.ExposeApiUrl;
import com.ocom.common.entity.card.EntityXfRecordProcess;
import com.ocom.common.enums.ResultEnum;
import com.ocom.common.request.company.GetComRequestRequest;
import com.ocom.common.request.payhandle.GetRecordByOrderNoRequest;
import com.ocom.common.request.simple.unicom.ConsEventRequest;
import com.ocom.common.request.simple.unicom.DevicesDataRequest;
import com.ocom.common.resp.Result;
import com.ocom.common.response.GetComRequestResponse;
import com.ocom.common.utils.DateUtil;
import com.ocom.common.utils.ResultUtil;
import com.ocom.common.utils.SignUtils;
import com.ocom.exposeapi.feign.CompanyClientService;
import com.ocom.exposeapi.feign.HumanFeignService;
import com.ocom.exposeapi.feign.PayConfigClientService;
import com.ocom.exposeapi.feign.PayHandleClientService;
import com.ocom.exposeapi.vo.unicom.UnicomResult;
import com.ocom.redis.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.HttpPost;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@Slf4j
@RestController
public class UnicomController {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private CompanyClientService companyClientService;
    @Autowired
    private HumanFeignService humanFeignService;
    @Autowired
    private PayConfigClientService payConfigClientService;
    @Autowired
    private PayHandleClientService payHandleClientService;
    @Resource
    private RedisUtil redisUtil;

    private static final String APP_ID = "2gRBLmU3Cz";
    private static final String APP_SECRET = "t4nBpIbWW3";
    private static final String url = "https://iot.unimip.cn/gw";
    private static final String DOCK_CODE = "unicom";
    private static final String SERVER_CODE = "unicom#ocom";
    private static final String CONSUME_RECORD_DOCK_API_CODE = "unicom#consEvent";

    @PostMapping(ExposeApiUrl.URL_ExposeApi_UnicomConsEvent)
    public Result unicomConsEvent(@RequestParam Long comId, @RequestParam String tradeNo) {
        logger.info("unicomConsEvent:设备数据联通上报接口---------------【{}】", tradeNo);

        Result response = ResultUtil.success();
        try {

            GetRecordByOrderNoRequest getRecordByOrderNoRequest = new GetRecordByOrderNoRequest();
            getRecordByOrderNoRequest.setCompanyId(comId);
            getRecordByOrderNoRequest.setPId(null);
            getRecordByOrderNoRequest.setOrderNo(tradeNo);
            Result getRecordByOrdernoResult = payHandleClientService.getRecordByOrderno(getRecordByOrderNoRequest);
            if (200 == getRecordByOrdernoResult.getCode() && null != getRecordByOrdernoResult.getData()) {
                EntityXfRecordProcess xfRecordProcesses = JSON.parseObject(JSON.toJSONString(getRecordByOrdernoResult.getData()), EntityXfRecordProcess.class);

                String lockKey = "unicomConsEvent:" + xfRecordProcesses.getOrderNo();

                if (null != xfRecordProcesses && -1 != xfRecordProcesses.getPayState() && 0 == xfRecordProcesses.getSendState() && redisUtil.lock(lockKey, 60 * 60)) {
                    String getComRequestKey = "getComRequest:" + CONSUME_RECORD_DOCK_API_CODE + ":" + comId;
                    Object o = redisUtil.get(getComRequestKey);
                    GetComRequestResponse getComRequestResponse = null;
                    if (null == o) {
                        GetComRequestRequest getComRequestRequest = new GetComRequestRequest();
                        getComRequestRequest.setComId(comId);
                        getComRequestRequest.setDockCode(DOCK_CODE);
                        getComRequestRequest.setDockApiCode(CONSUME_RECORD_DOCK_API_CODE);
                        logger.info("unicomConsEvent:getComRequest---------------:" + getComRequestRequest.toString());

                        Result getComRequestResult = companyClientService.getComRequest(getComRequestRequest);
                        logger.info("unicomConsEvent:getComRequest结果---------------:" + getComRequestResult.toString());
                        if (200 == getComRequestResult.getCode() && null != getComRequestResult.getData()) {
                            getComRequestResponse = JSON.parseObject(JSON.toJSONString(getComRequestResult.getData()), GetComRequestResponse.class);
                            redisUtil.set(getComRequestKey, JSON.toJSONString(getComRequestResponse), 4 * 60 * 60l);
                        }
                    } else {
                        getComRequestResponse = JSON.parseObject(JSON.parse(JSON.toJSONString(o)).toString(), GetComRequestResponse.class);
                    }

                    if (null != getComRequestResponse && StringUtils.isNotBlank(getComRequestResponse.getRequestUrl())) {

                        HttpPost post = new HttpPost(getComRequestResponse.getRequestUrl());

                        JSONObject devicesJson = JSON.parseObject(getComRequestResponse.getRsaPri());
                        String deviceKey = devicesJson.getString(xfRecordProcesses.getDeviceNo());
                        UnicomResult result = null;

                        log.info("unicomConsEvent:----------------------deviceKey：【】", deviceKey);

                        if (StringUtils.isNotBlank(deviceKey)) {
                            DevicesDataRequest devicesDataRequest = new DevicesDataRequest();
                            devicesDataRequest.setProductKey(getComRequestResponse.getRsaPub());
                            devicesDataRequest.setDeviceKey(deviceKey);

                            DevicesDataRequest.Data data = devicesDataRequest.getData();
                            DevicesDataRequest.Events events = devicesDataRequest.getEvents();
                            DevicesDataRequest.ConsEvent consEvent = devicesDataRequest.getConsEvent();
                            DevicesDataRequest.Value value = devicesDataRequest.getValue();

                            value.setMachNo(xfRecordProcesses.getDeviceNo());
                            value.setOrderNo(xfRecordProcesses.getOrderNo());
                            value.setConsTime(DateUtil.getDateTime(xfRecordProcesses.getConsTime()));
                            value.setConsState(xfRecordProcesses.getConsState());
                            value.setConsMoney(Math.abs(xfRecordProcesses.getRealMoney()));
                            value.setDescribe(xfRecordProcesses.getPName() + "(" + xfRecordProcesses.getPCode() + ")");

                            consEvent.setValue(value);
                            consEvent.setEventType("info");

                            events.setConsEvent(consEvent);

                            data.setEvents(events);

                            devicesDataRequest.setData(data);

                            ConsEventRequest consEventRequest = new ConsEventRequest();
                            consEventRequest.setAppId(getComRequestResponse.getComAppid());
                            consEventRequest.setUri(getComRequestResponse.getRequestUrl());

                            String sign = SignUtils.createSign(consEventRequest, null, "appKey", getComRequestResponse.getMd5key());

                            post.addHeader("appId", consEventRequest.getAppId());
                            post.addHeader("nonce", consEventRequest.getNonce());
                            post.addHeader("tm", String.valueOf(consEventRequest.getTm()));
                            post.addHeader("sign", sign);

                            post.addHeader("Content-Type", "application/json;charset=utf-8");

                            JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(devicesDataRequest));
                            jsonObject.remove("event");
                            jsonObject.remove("events");
                            jsonObject.remove("consEvent");
                            jsonObject.remove("value");

                            log.info("unicomConsEvent:jsonObject:{}", jsonObject);
                            String resultJson = HttpUtils.postsJson(post, jsonObject);

                            log.info("unicomConsEvent:----------------------resultJson：" + resultJson);
                            result = JSON.parseObject(resultJson, UnicomResult.class);
                        } else {
                            log.info("unicomConsEvent:----------------------跳过deviceKey为空：【】", tradeNo);
                            result = new UnicomResult();
                            result.setSuccess(true);
                        }

                        if (null != result && result.getSuccess()) {
                            logger.info("unicomConsEvent:----------------------订单上报成功:{}", xfRecordProcesses.getOrderNo());
                            payHandleClientService.sendByOrderno(xfRecordProcesses);
                        }

                    }
                    redisUtil.del(RedisUtil.LOCK_PREFIX + lockKey);
                } else {
                    logger.info("unicomConsEvent:----------------------设备数据联通上报失败:订单加锁失败或已上报 【{}】", lockKey);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.info("unicomConsEvent:----------------------设备数据联通上报异常:" + e.getMessage() + " 订单：" + tradeNo);
            response = ResultUtil.error(ResultEnum.Err_900);
        }
        return response;
    }


}
